//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
#include "ListE.h"
#include <stdio.h>
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
TListE <T>::TListE():length(0), first(NULL), final(NULL), previous(NULL), current(NULL), next(NULL) {}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
TListE <T>::TListE(T* newElement) {

  if (newElement) { this->first = this->final = new TNode <T> (newElement); this->length = 1;}
  else            { this->first = this->final = NULL; this->length = 0; }

  this->SetCurrent(this->first);

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
TListE <T>::TListE(TListE <T>* list) {

  this->length  = list->Length();

  if (!this->length)  this->first = this->final = NULL;
  else {

    TNode <T>* cursor = NULL;
    list->SetInitial();

    for(long i = 0; i < this->length; i++) {

      T* refNode = new T(*(list->GetNext()));
      TNode <T>* newNode = new TNode <T> (refNode);
      if (!i)     this->first = newNode;
      if (cursor) cursor->Next(newNode);
      newNode->Previous(cursor);
      cursor = newNode;

    }
    cursor->Next(NULL);
    this->final = cursor;

  }

  this->SetCurrent(this->first);

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
TListE <T>::TListE(TListE <T>& list) {

  this->length  = list.Length();

  if (!this->length)  this->first = this->final = NULL;
  else {

    TNode <T>* cursor = NULL;
    list.SetInitial();

    for(long i = 0; i < this->length; i++) {

      T* refNode = new T(*(list.GetNext()));
      TNode <T>* newNode = new TNode <T> (refNode);
      if (!i)     this->first = newNode;
      if (cursor) cursor->Next(newNode);
      newNode->Previous(cursor);
      cursor = newNode;

    }
    cursor->Next(NULL);
    this->final = cursor;

  }

  this->SetCurrent(this->first);

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
TListE <T>::~TListE() {

  TNode <T>* cursor;

  while (this->first) {
    cursor = this->first;
    this->first = this->first->Next();
    if (cursor) delete cursor;
  }

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
TNode <T>* TListE <T>::PosNode(long pos) {

  TNode <T>* cursor = this->first;
  for (long i = 0; i < pos; i++)
    cursor = cursor->Next();

  this->SetCurrent(cursor);

  return cursor;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
void TListE <T>::SetCurrent(TNode <T>* cursor) {

  this->current  = cursor;

  if (this->current) {
    this->previous = this->current->Previous();
    this->next     = this->current->Next();
  }
  else this->previous = this->next = NULL;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
void TListE <T>::Add(T* newElement) {

  if (!newElement) return;

  TNode <T>* newNode = new TNode <T> (newElement);

  if (this->first) {
    this->final->Next(newNode);
    newNode->Previous(this->final);
    this->final = newNode;
  }
  else this->first = this->final = newNode;

  this->SetCurrent(newNode);
  this->length++;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
void TListE <T>::AddIni(T* newElement) {

  if (!newElement) return;

  TNode <T>* newNode = new TNode <T> (newElement);
  newNode->Next(this->first);

  this->first->Previous(newNode);
  this->first = newNode;
  this->SetCurrent(this->first);
  this->length++;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
void TListE <T>::AddNode(TNode <T>* newNode) {

  if (!newNode) return;

  if (this->first) {
    this->final->Next(newNode);
    newNode->Previous(this->final);
    newNode->Next(NULL);
    this->final = newNode;
  }
  else this->first = this->final = newNode;

  this->SetCurrent(newNode);
  this->length++;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
void TListE <T>::AddNodeIni(TNode <T>* newNode) {

  if (!newNode) return;

  newNode->Previous(NULL);
  this->first->Previous(newNode);
  newNode->Next(this->first);
  this->first = newNode;
  this->SetCurrent(this->first);
  this->length++;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
void TListE <T>::Add(T newElement) {

  T* element = new T(newElement);

  TNode <T>* newNode = new TNode <T> (element);

  if (this->first) {
    this->final->Next(newNode);
    newNode->Previous(this->final);
    this->final = newNode;
  }
  else this->first = this->final = newNode;

  this->SetCurrent(newNode);
  this->length++;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
void TListE <T>::AddIni(T newElement) {

  T* element = new T(newElement);

  TNode <T>* newNode = new TNode <T> (element);
  newNode->Next(this->first);
  this->first->Previous(newNode);
  this->first = newNode;
  this->SetCurrent(this->first);
  this->length++;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
void TListE <T>::AddNode(TNode <T> newNode) {

  T*         element = new T(newNode.Info());
  TNode <T>* node    = new TNode <T>(element);

  if (this->first) {
    this->final->Next(node);
    node->Previous(this->final);
    node->Next(NULL);
    this->final = node;
  }
  else this->first = this->final = node;

  this->SetCurrent(node);
  this->length++;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
void TListE <T>::AddNodeIni(TNode <T> newNode) {

  T*         element = new T(newNode.Info());
  TNode <T>* node    = new TNode <T>(element);

  node->Previous(NULL);
  this->first->Previous(node);
  node->Next(this->first);
  this->first = node;
  this->SetCurrent(this->first);
  this->length++;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
void TListE <T>::Delete(long pos) {

  if ((pos < 0) || (pos >= this->length)) return;

  TNode <T>* cursor = this->first;

  if (!pos) {
    this->first    = this->first->Next();
    if (this->first) this->first->Previous(NULL);
    this->SetCurrent(this->first);
  }
  else if (pos == this->length - 1) {
    cursor         = this->final;
    this->final    = this->final->Previous();
    this->current  = this->final;
    this->previous = this->final->Previous();
    this->final->Next(NULL);
    this->next     = this->final->Next();
  }
  else {
    for (long i = 0; i < pos - 1; i++) cursor = cursor->Next();
    TNode <T>* nodeDel = cursor->Next();
    cursor->Next(nodeDel->Next());
    nodeDel->Next()->Previous(cursor);
    this->SetCurrent(cursor->Next());
    cursor = nodeDel;
  }

  if (cursor) delete cursor;

  this->length--;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
void TListE <T>::Delete(T* value) {

  if (!value) return;

  TNode <T>* nodeDel = this->first;
  TNode <T>* cursor  = nodeDel;
  long       pos     = 0;

  while((nodeDel) && (*nodeDel->Info() != *value)) {
    cursor  = nodeDel;
    nodeDel = nodeDel->Next();
    pos++;
  }

  if (pos > this->length) return;

  if (!pos) {
    nodeDel        = this->first;
    if (this->first) this->first    = this->first->Next();
    if (this->first) this->first->Previous(NULL);
    this->SetCurrent(this->first);
  }
  else if (pos == this->length - 1) {
    nodeDel        = this->final;
    this->final    = this->final->Previous();
    this->current  = this->final;
    this->previous = this->final->Previous();
    this->final->Next(NULL);
    this->next     = this->final->Next();
  }
  else {
    cursor->Next(nodeDel->Next());
    nodeDel->Next()->Previous(cursor);
    this->SetCurrent(cursor->Next());
  }

  if (nodeDel) delete nodeDel;

  this->length--;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
void TListE <T>::DeleteCurrent() {

  if (!this->current) return;

  TNode <T>* nodeDel = this->current;

  if (nodeDel == this->first) {
    this->first    = nodeDel->Next();
    if (this->first) this->first->Previous(NULL);
    this->SetCurrent(this->first);
  }
  else if (nodeDel == this->final) {
    this->final    = nodeDel->Previous();
    this->final->Next(NULL);
    this->current  = this->final;
    this->previous = this->final->Previous();
    this->next     = this->final->Next();
  }
  else {
    nodeDel->Previous()->Next(nodeDel->Next());
    nodeDel->Next()->Previous(nodeDel->Previous());
    this->SetCurrent(nodeDel->Next());
  }

  if (nodeDel) delete nodeDel;

  this->length--;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
void TListE <T>::Insert(T* newElement, long pos) {

  if ((pos < 0) || (pos > this->length) || !newElement) return;

  TNode <T>* newNode = new TNode <T> (newElement);

  if (!pos) {
    newNode->Next(this->first);
    this->first->Previous(newNode);
    this->first = newNode;
  }
  else if (pos == this->length) {
    this->final->Next(newNode);
    newNode->Previous(this->final);
    this->final = newNode;
  }
  else if (pos == this->length - 1) {
    newNode->Next(this->final);
    newNode->Previous(this->final->Previous());
    this->final->Previous()->Next(newNode);
    this->final->Previous(newNode);
  }
  else {
    TNode <T>* cursor = this->first;
    long    count  = 0;
    while (count < pos) {
      cursor = cursor->Next();
      count++;
    }
    newNode->Next(cursor);
    newNode->Previous(cursor->Previous());
    cursor->Previous()->Next(newNode);
    cursor->Previous(newNode);
  }

  this->SetCurrent(newNode);
  this->length++;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
void TListE <T>::InsertBeforeCurrent(T* newElement) {

  if (!newElement || !this->current) return;

  TNode <T>* newNode = new TNode <T> (newElement);

  if (this->current == this->first) {
    newNode->Next(this->first);
    this->first->Previous(newNode);
    this->first = newNode;
  }
  else if (this->current == this->final) {
    newNode->Previous(this->final->Previous());
    this->final->Previous()->Next(newNode);
    newNode->Next(this->final);
    this->final->Previous(newNode);
  }
  else {
    newNode->Previous(this->current->Previous());
    newNode->Next(this->current);
    this->current->Previous()->Next(newNode);
    this->current->Previous(newNode);
  }

  this->SetCurrent(newNode);
  this->length++;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
void TListE <T>::InsertAfterCurrent(T* newElement) {

  if (!newElement || !this->current) return;

  TNode <T>* newNode = new TNode <T> (newElement);

  if (this->current == this->first) {
    newNode->Next(this->first->Next());
    newNode->Previous(this->first);
    this->first->Next(newNode);
  }
  else if (this->current == this->final) {
    this->final->Next(newNode);
    newNode->Previous(this->final);
    this->final = newNode;
  }
  else {
    newNode->Next(this->current->Next());
    newNode->Previous(this->current);
    this->current->Next(newNode);
  }

  this->SetCurrent(newNode);
  this->length++;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
void TListE <T>::InsertNode(TNode <T>* newNode, long pos) {

  if ((pos < 0) || (pos > this->length) || !newNode) return;

  if (!pos) {
    newNode->Next(this->first);
    newNode->Previous(NULL);
    this->first->Previous(newNode);
    this->first = newNode;
  }
  else if (pos == this->length) {
    this->final->Next(newNode);
    newNode->Previous(this->final);
    newNode->Next(NULL);
    this->final = newNode;
  }
  else if (pos == this->length - 1) {
    newNode->Next(this->final);
    newNode->Previous(this->final->Previous());
    this->final->Previous()->Next(newNode);
    this->final->Previous(newNode);
  }
  else {
    TNode <T>* cursor = this->first;
    long    count  = 0;
    while (count < pos) {
      cursor = cursor->Next();
      count++;
    }
    newNode->Next(cursor);
    newNode->Previous(cursor->Previous());
    cursor->Previous()->Next(newNode);
    cursor->Previous(newNode);
  }

  this->SetCurrent(newNode);
  this->length++;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
void TListE <T>::InsertNodeBeforeCurrent(TNode <T>* newNode) {

  if (!this->current || !newNode) return;

  if (this->current == this->first) {
    newNode->Next(this->first);
    newNode->Previous(NULL);
    this->first->Previous(newNode);
    this->first = newNode;
  }
  else if (this->current == this->final) {
    newNode->Previous(this->final->Previous());
    newNode->Next(NULL);
    this->final->Previous()->Next(newNode);
    newNode->Next(this->final);
    this->final->Previous(newNode);
  }
  else {
    newNode->Previous(this->current->Previous());
    newNode->Next(this->current);
    this->current->Previous()->Next(newNode);
    this->current->Previous(newNode);
  }

  this->SetCurrent(newNode);
  this->length++;

 }
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
void TListE <T>::InsertNodeAfterCurrent(TNode <T>* newNode) {

  if (!this->current || !newNode) return;

  if (this->current == this->first) {
    newNode->Next(this->first->Next());
    newNode->Previous(this->first);
    this->first->Next(newNode);
  }
  else if (this->current == this->final) {
    this->final->Next(newNode);
    newNode->Previous(this->final);
    newNode->Next(NULL);
    this->final = newNode;
  }
  else {
    newNode->Next(this->current->Next());
    newNode->Previous(this->current);
    this->current->Next(newNode);
  }

  this->SetCurrent(newNode);
  this->length++;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
T* TListE <T>::Transfer(long pos) {

  if ((pos < 0) || (pos >= this->length) || !this->first) return NULL;

  TNode <T>* cursor = this->first;

  if (!pos) {
    this->first = this->first->Next();
    if (this->first) {
      this->first->Previous(NULL);
      this->SetCurrent(this->first);
    }
    else this->final = this->current = this->previous = this->next = NULL;
  }
  else if (pos == this->length - 1) {
    cursor = this->final;
    this->final = cursor->Previous();
    this->final->Next(NULL);
    this->SetCurrent(this->final);
  }
  else {
    for (long i = 0; i < pos - 1; i++)
     cursor = cursor->Next();

    TNode <T>* nodeDel = cursor->Next();
    cursor->Next(nodeDel->Next());
    nodeDel->Next()->Previous(cursor);
    this->SetCurrent(cursor->Next());
    cursor         = nodeDel;
  }

  this->length--;

  T* Info = cursor->Info();

  cursor->Info(NULL);
  if (cursor) delete cursor;

  return Info;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
T* TListE <T>::TransferCurrent() {

  if (!this->current) return NULL;

  TNode <T>* cursor = this->current;

  if (cursor == this->first) {
    this->first    = cursor->Next();
    if (this->first) {
      this->first->Previous(NULL);
      this->SetCurrent(this->first);
    }
    else this->final = this->current = this->previous = this->next = NULL;
  }
  else if (cursor == this->final) {
    this->final    = cursor->Previous();
    this->final->Next(NULL);
    this->SetCurrent(this->final);
  }
  else {
    cursor->Previous()->Next(cursor->Next());
    this->SetCurrent(cursor->Next());
  }

  this->length--;

  T* Info = cursor->Info();

  cursor->Info(NULL);
  if (cursor) delete cursor;

  return Info;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
TNode <T>* TListE <T>::TransferNode(long pos) {

  if ((pos < 0) || (pos >= this->length) || !this->first) return NULL;

  TNode <T>* cursor = this->first;

  if (!pos) {
    this->first = this->first->Next();
    if (this->first) {
      this->first->Previous(NULL);
      this->SetCurrent(this->first);
    }
    else this->final = this->current = this->previous = this->next = NULL;
  }
  else if (pos == this->length - 1) {
    cursor = this->final;
    this->final = cursor->Previous();
    this->final->Next(NULL);
    this->SetCurrent(this->final);
  }
  else {
    for (long i = 0; i < pos - 1; i++)
      cursor = cursor->Next();

    TNode <T>* nodeDel = cursor->Next();
    cursor->Next(nodeDel->Next());
    nodeDel->Next()->Previous(cursor);
    this->SetCurrent(cursor->Next());
    cursor         = nodeDel;
  }

  this->length--;

  cursor->Next(NULL);
  cursor->Previous(NULL);

  return cursor;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
TNode <T>* TListE <T>::TransferCurrentNode() {

  if (!this->current) return;

  TNode <T>* cursor = this->current;

  if (cursor == this->first) {
    this->first    = cursor->Next();
    if (this->first) {
      this->first->Previous(NULL);
      this->SetCurrent(this->first);
    }
    else this->final = this->current = this->previous = this->next = NULL;
  }
  else if (cursor == this->final) {
    this->final    = cursor->Previous();
    this->final->Next(NULL);
    this->SetCurrent(this->final);
  }
  else {
    cursor->Previous()->Next(cursor->Next());
    this->SetCurrent(cursor->Next());
  }

  this->length--;

  cursor->Next(NULL);
  cursor->Previous(NULL);

  return cursor;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
void TListE <T>::TransferAll() {

  while (this->length) this->Transfer(0);

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
void TListE <T>::Destroy(long pos) {

  if ((pos < 0) || (pos >= this->length)) return;

  TNode <T>* cursor = this->first;

  if (!pos) {
    this->first    = this->first->Next();
    if (this->first) {
      this->first->Previous(NULL);
      this->SetCurrent(this->first);
    }
    else this->final = this->current = this->previous = this->next = NULL;
  }
  else if (pos == this->length - 1) {
    cursor = this->final;
    this->final = this->final->Previous();
    this->final->Next(NULL);
    this->SetCurrent(this->final);
  }
  else {
    for (long i = 0; i < pos - 1; i++)
      cursor = cursor->Next();
    TNode <T>* nodeDel = cursor->Next();
    cursor->Next(nodeDel->Next());
    nodeDel->Next()->Previous(cursor);
    this->SetCurrent(cursor->Next());
    cursor        = nodeDel;
  }

  if (cursor) delete cursor;

  this->length--;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
void TListE <T>::DestroyCurrent() {

  if (!this->current) return;

  TNode <T>* cursor = this->current;

  if (cursor == this->first) {
    this->first    = this->first->Next();
    if (this->first) {
      this->first->Previous(NULL);
      this->SetCurrent(this->first);
    }
    else this->final = this->current = this->previous = this->next = NULL;
  }
  else if (cursor == this->final) {
    this->final   = this->final->Previous();
    this->final->Next(NULL);
    this->SetCurrent(this->final);
  }
  else {
    cursor->Previous()->Next(cursor->Next());
    cursor->Next()->Previous(cursor);
    this->SetCurrent(cursor->Next());
  }

  if (cursor) delete cursor;

  this->length--;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
bool TListE <T>::Update(T* value, long pos) {

  if ((pos < 0) || (pos > this->length)) return false;

  this->Delete(pos);
  this->InsertBeforeCurrent(value);

  return true;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
long TListE <T>::Length() { return this->length; }
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
void TListE <T>::SetPosition(long pos) {

  if ((pos < 0) || (pos >= this->length)) return;

  if (!pos) {
    this->current  = NULL;
    this->previous = NULL;
    this->next     = this->first;
    return;
  }

  TNode <T>* cursor = this->first;
  for (long i = 0; i < pos - 1; i++) cursor = cursor->Next();

  this->SetCurrent(cursor);

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
void TListE <T>::SetInitial() {

  this->current  = NULL;
  this->previous = NULL;
  this->next     = this->first;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
bool TListE <T>::SetNext() {

  TNode <T>* cursor = this->next;
  if (cursor) {
    this->SetCurrent(cursor);
    return true;
  }
  return false;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
T* TListE <T>::Get(long pos) {


  if ((pos < 0) || (pos >= this->length)) return NULL;

  TNode <T>* cursor = this->first;
  for (long i = 0; i < pos; i++) cursor = cursor->Next();

  this->SetCurrent(cursor);
  return cursor->Info();

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
T* TListE <T>::GetPrevious() {

  TNode <T>* cursor = this->previous;
  if (cursor) {
    this->SetCurrent(cursor);
    return cursor->Info();
  }
  return NULL;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
T* TListE <T>::GetCurrent() {
  return (this->current)?this->current->Info():NULL;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
T* TListE <T>::GetNext() {

  TNode <T>* cursor = this->next;
  if (cursor) {
    this->SetCurrent(cursor);
    return cursor->Info();
  }
  return NULL;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
T* TListE <T>::GetFirst() {

  TNode <T>* cursor = this->first;
  if (cursor) {
    this->SetCurrent(cursor);
    return cursor->Info();
  }
  return NULL;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
T* TListE <T>::GetFinal() {

  TNode <T>* cursor = this->final;
  if (cursor) {
    this->SetCurrent(cursor);
    return cursor->Info();
  }
  return NULL;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
TNode <T>* TListE <T>::GetNode(long pos) {

  if ((pos < 0) || (pos >= this->length)) return NULL;

  TNode <T>* cursor = this->first;
  for (long i = 0; i < pos; i++) cursor = cursor->Next();

  this->SetCurrent(cursor);
  return cursor;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
TNode <T>* TListE <T>::GetPreviousNode() {

  TNode <T>* cursor = this->previous;
  if (cursor) this->SetCurrent(cursor);
  return cursor;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
TNode <T>* TListE <T>::GetCurrentNode() {
  return (this->current)?this->current:NULL;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
TNode <T>* TListE <T>::GetNextNode() {

  TNode <T>* cursor = this->next;
  if (cursor) this->SetCurrent(cursor);
  return cursor;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
TNode <T>* TListE <T>::GetFirstNode() {

  TNode <T>* cursor = this->first;
  if (cursor) this->SetCurrent(cursor);
  return cursor;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
TNode <T>* TListE <T>::GetFinalNode() {

  TNode <T>* cursor = this->final;
  if (cursor) this->SetCurrent(cursor);
  return cursor;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
void TListE <T>::ExchangeElement(T* element1, T* element2) {

  T* element = new T;

  *element  = *element1;
  *element1 = *element2;
  *element2 = *element;

  if (element) delete element;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
void TListE <T>::ExchangeNode(TNode <T>* node1, TNode <T>* node2) {

  TNode <T>* cursor = new TNode <T>;

  cursor->Info(node1->Info()); node1->Info(NULL);
  node1->Info(node2->Info());  node2->Info(NULL);
  node2->Info(cursor->Info()); cursor->Info(NULL);

  if (cursor) delete cursor;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
void TListE <T>::ExchangeBlocks(long iniBlockA, long endBlockA, long iniBlockB, long endBlockB) {

  if ((iniBlockA < 0) || (iniBlockA >= this->length)       ||
      (endBlockA < 0) || (endBlockA >= this->length)       ||
      (iniBlockB < 0) || (iniBlockB >= this->length)       ||
      (endBlockB < 0) || (endBlockB >= this->length)       ||
      (iniBlockA > endBlockA)                              ||
      (iniBlockB > endBlockB)                              ||
      ((iniBlockA < iniBlockB) && (endBlockA > iniBlockB)) ||
      ((iniBlockB < iniBlockA) && (endBlockB > iniBlockA)))
    return;

  TNode <T>* iniNodeA = this->GetNode(iniBlockA);
  TNode <T>* endNodeA = this->GetNode(endBlockA);

  TNode <T>* iniNodeB = this->GetNode(iniBlockB);
  TNode <T>* endNodeB = this->GetNode(endBlockB);

  TNode <T>* temporal = NULL;

  temporal = iniNodeA->Previous();
  iniNodeA->Previous(iniNodeB->Previous());
  iniNodeB->Previous(temporal);

  if (iniNodeA->Previous()) iniNodeA->Previous()->Next(iniNodeA);
  if (iniNodeB->Previous()) iniNodeB->Previous()->Next(iniNodeB);

  temporal = endNodeA->Next();
  endNodeA->Next(endNodeB->Next());
  endNodeB->Next(temporal);

  if (endNodeA->Next()) endNodeA->Next()->Previous(endNodeA);
  if (endNodeB->Next()) endNodeB->Next()->Previous(endNodeB);

  this->SetPosition(0);

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
void TListE <T>::ExchangeBlocks(long iniBlock, long endBlock, long position) {

  if ((iniBlock < 0)          || (iniBlock >= this->length) ||
      (endBlock < 0)          || (endBlock >= this->length) ||
      (iniBlock > endBlock)   || (position < 0)             ||
      ((position >= iniBlock) && (position <= endBlock))    ||
      (position > this->length))
    return;

  TNode <T>* iniNode = this->GetNode(iniBlock);
  TNode <T>* endNode = this->GetNode(endBlock);
  TNode <T>* posNode = this->GetNode(position);

  if (iniNode->Previous()) iniNode->Previous()->Next(endNode->Next());
  if (endNode->Next())     endNode->Next()->Previous(iniNode->Previous());

  iniNode->Previous(posNode->Previous());
  if (iniNode->Previous()) iniNode->Previous()->Next(iniNode);
  endNode->Next(posNode);
  posNode->Previous(endNode);

  if (!position) this->first = iniNode;

  this->SetPosition(0);

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
void TListE <T>::ForEach(TFunctionAction fAction, void* reference = NULL) {

  TNode <T>* cursor = this->first;

  while (cursor) {
    fAction(cursor, reference);
    cursor = cursor->Next();
  }

  this->SetCurrent(cursor);

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
void TListE <T>::ForEachFrom(TNode <T>* cursor, TFunctionAction fAction, void* reference = NULL) {

  while (cursor) {
    fAction(cursor, reference);
    cursor = cursor->Next();
  }

  this->SetCurrent(cursor);

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
T* TListE <T>::FirstOcurrence(TFunctionConditionalB fCondition, void* reference = NULL) {

  TNode <T>* cursor = this->first;
  bool       finded = false;

  while (cursor && !finded) {
    if (fCondition(cursor, reference)) finded = true;
    else cursor = cursor->Next();
  }

  this->SetCurrent(cursor);
  return ((finded)?cursor->Info():NULL);

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
long TListE <T>::FirstOcurrencePosition(TFunctionConditionalB fCondition, void* reference = NULL) {

  TNode <T>* cursor   = this->first;
  bool       finded   = false;
  long       position = 0;

  while (cursor && !finded) {
    if (fCondition(cursor, reference)) finded = true;
    else { cursor = cursor->Next(); position++; }
  }

  this->SetCurrent(cursor);
  return ((finded)?position:-1);

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
T* TListE <T>::FirstOcurrence(TFunctionConditionalBParameters fCondition, void* reference = NULL, void* parameters = NULL) {

  TNode <T>* cursor = this->first;
  bool       finded = false;

  while (cursor && !finded) {
    if (fCondition(cursor, reference, parameters)) finded = true;
    else cursor = cursor->Next();
  }

  this->SetCurrent(cursor);
  return ((finded)? cursor->Info():NULL);

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
T* TListE <T>::FirstOcurrenceFrom(TNode <T>* cursor, TFunctionConditionalB fCondition, void* reference = NULL) {

  bool   finded = false;

  while (cursor && !finded) {
    if (fCondition(cursor, reference)) finded = true;
    else cursor = cursor->Next();
  }

  this->SetCurrent(cursor);
  return ((finded)? cursor->Info():NULL);

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
void TListE <T>::AllOcurrence(TFunctionConditionalB fCondition, TListE <T>* ListT, void* reference = NULL) {

  TNode <T>* cursor = this->first;

  ListT->Clear();

  while (cursor) {
    if (fCondition(cursor, reference))
      ListT->Add(cursor->Info());
    cursor = cursor->Next();
  }

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
void TListE <T>::AllOcurrence(TFunctionConditionalBParameters fCondition, TListE <T>* ListT, void* reference = NULL, void* parameters = NULL) {

  TNode <T>* cursor = this->first;

  ListT->Clear();

  while (cursor) {
    if (fCondition(cursor, reference, parameters))
      ListT->Add(cursor->Info());
    cursor = cursor->Next();
  }

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
void TListE <T>::ConsecutiveSubList(TFunctionConditionalB fCondition, TListE <T>* ListT, void* reference = NULL) {

  TNode <T>* cursor = this->first;

  ListT->Clear();

  while (cursor) {
    if (fCondition(cursor, reference)) {
      if (ListT->first) {
        ListT->final->Next(cursor);
        cursor->Previous(ListT->final);
        ListT->final = cursor;
      }
      else ListT->first = ListT->final = cursor;
      ListT->length++;
    }
    cursor = cursor->Next();
  }

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
void TListE <T>::ConsecutiveSubList(TFunctionConditionalBParameters fCondition, TListE <T>* ListT, void* reference = NULL, void* parameters = NULL) {

  TNode <T>* cursor = this->first;

  ListT->Clear();

  while (cursor) {
    if (fCondition(cursor, reference, parameters)){
      if (ListT->first) {
        ListT->final->Next(cursor);
        cursor->Previous(ListT->final);
        ListT->final = cursor;
      }
      else ListT->first = ListT->final = cursor;
      ListT->length++;
    }
    cursor = cursor->Next();
  }

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
void TListE <T>::CleanConsecutiveSubList() {

  this->length   = 0;
  this->first    = NULL;
  this->final    = NULL;
  this->SetCurrent(NULL);

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
void TListE <T>::AllOcurrenceFrom(TNode <T>* cursor, TFunctionConditionalB fCondition, TListE <T>* ListT, void* reference = NULL) {

  ListT->Clear();

  while (cursor) {
    if (fCondition(cursor, reference))
      ListT->Add(cursor->Info());
    cursor = cursor->Next();
  }

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
void TListE <T>::AllOcurrenceCond(TFunctionConditionalI fCondition, TListE <T>* ListT, void* reference = NULL) {

  TNode <T>* cursor = this->first;

  ListT->Clear();

  while (cursor) {
    int condition = fCondition(cursor, reference);
    if      (condition ==  1) ListT->Add(cursor->Info());
    else if (condition == -1) break;
    cursor = cursor->Next();
  }

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
void TListE <T>::AllOcurrenceCondFrom(TNode <T>* cursor, TFunctionConditionalI fCondition, TListE <T>* ListT, void* reference = NULL) {

  ListT->Clear();

  while (cursor) {
    int condition = fCondition(cursor, reference);
    if      (condition ==  1) ListT->Add(cursor->Info());
    else if (condition == -1) break;
    cursor = cursor->Next();
  }

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
long TListE <T>::NumberOcurrence(TFunctionConditionalB fCondition, void* reference = NULL) {

  TNode <T>* cursor = this->first;
  long       number = 0;

  while (cursor) {
    if (fCondition(cursor, reference))
      number++;
    cursor = cursor->Next();
  }

  return number;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
long TListE <T>::NumberOcurrence(TFunctionConditionalBParameters fCondition, void* reference = NULL, void* parameters = NULL) {

  TNode <T>* cursor = this->first;
  long       number = 0;

  while (cursor) {
    if (fCondition(cursor, reference, parameters))
      number++;
    cursor = cursor->Next();
  }

  return number;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
long TListE <T>::NumberOcurrenceFrom(TNode <T>* cursor, TFunctionConditionalB fCondition, void* reference = NULL) {

  long number = 0;

  while (cursor) {
    if (fCondition(cursor, reference))
      number++;
    cursor = cursor->Next();
  }

  return number;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
long TListE <T>::NumberOcurrenceFrom(TNode <T>* cursor, TFunctionConditionalBParameters fCondition, void* reference = NULL, void* parameters = NULL) {

  long number = 0;

  while (cursor) {
    if (fCondition(cursor, reference, parameters))
      number++;
    cursor = cursor->Next();
  }

  return number;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
void TListE <T>::RepresentativeOcurrencesAfterOrdered(TFunctionConditionalBParameters fCondition, TListE <T>* ListT, void* parameters = NULL) {

  *ListT = *this;

  long position = 0;

  while (position < ListT->length - 1)
    if (fCondition(ListT->PosNode(position), ListT->PosNode(position + 1), parameters))
      ListT->Transfer(position);
    else position++;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
void TListE <T>::RepresentativeOcurrences(TFunctionConditionalBParameters fCondition, TListE <T>* ListT, void* parameters = NULL) {

  *ListT = *this;

  long positionReference = 0, positionRelative = 0;

  while (positionReference < ListT->length - 1) {
    positionRelative = positionReference + 1;
    while (positionRelative < ListT->length)
      if (fCondition(ListT->PosNode(positionReference), ListT->PosNode(positionRelative), parameters))
        ListT->Transfer(positionRelative);
      else positionRelative++;
    positionReference++;
  }

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
void TListE <T>::OrderList(TFunctionConditionalB fCondition, void* reference = NULL) {

  for (long i = 0; i < this->length - 1; i++)
    for (long j = i + 1; j < this->length; j++)
      if (fCondition(this->PosNode(i), this->PosNode(j))) {
        void* TempInfo = this->PosNode(i)->Info();
        this->PosNode(i)->Info(this->PosNode(j)->Info());
        this->PosNode(j)->Info(TempInfo);
      }

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
void TListE <T>::OrderListCentered(TFunctionConditionalD fCondition, void* reference = NULL) {

  if (!reference) return;

  TListE <T>* listTmp   = new TListE <T>;
  TListE <T>* listNew   = new TListE <T>;
  TNode  <T>* centroid  = (TNode <T>*)reference;
  bool        condition = false;

  *(listTmp) = *this;

  for (long i = 0; i < listTmp->Length(); i++)
    if (*(listTmp->Get(i)) == *(centroid->Info())) {
      listNew->AddNode(listTmp->TransferNode(i));
      condition = true;
      break;
    }

  if (!condition) {
    listTmp->TransferAll(); if (listTmp) delete listTmp;
    listNew->TransferAll(); if (listNew) delete listNew;
    return;
  }

  bool flagBefore = true;
  bool flagSelect = false;

  while (listTmp->Length()) {

    TNode <T>* betterNode = listTmp->GetFirstNode();

    if (!betterNode) {
      listTmp->TransferAll(); if (listTmp) delete listTmp;
      listNew->TransferAll(); if (listNew) delete listNew;
      return;
    }

    double valueComp = fCondition(betterNode, centroid);
    long   position  = 0;

    for (long i = 0; i < listTmp->Length(); i++) {
      double tmpValue = fCondition(listTmp->GetNode(i), centroid);
      if (valueComp < tmpValue) { valueComp = tmpValue; position = i; }
    }

    if (!flagSelect) {

      TNode <T>* element = listTmp->TransferNode(position);

      if (!listTmp->GetFirstNode()) {
        if (flagBefore) listNew->AddNode(element);
        else            listNew->AddNodeIni(element);
        continue;
      }

      if (fCondition(listNew->GetFinalNode(), element) > fCondition(listNew->GetFirstNode(), element)) {
        listNew->AddNode(element);
        flagBefore = true;
      }
      else {
        listNew->AddNodeIni(element);
        flagBefore = false;
      }

    }
    else {
      if (flagBefore) listNew->AddNodeIni(listTmp->TransferNode(position));
      else            listNew->AddNode(listTmp->TransferNode(position));
    }

    flagSelect = !flagSelect;

  }

  for (long i = 0; i < this->Length(); i++) {
    this->GetNode(i)->Info(NULL);
    this->GetNode(i)->Info(listNew->GetNode(i)->Info());
  }

  listTmp->TransferAll();
  listNew->TransferAll();

  if (listTmp) delete listTmp;
  if (listNew) delete listNew;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
void TListE <T>::OrderListByList(TFunctionConditionalB fCondition, TListE <T>* ListT) {

  if (!ListT || !ListT->Length()) return;

  for (int i = 0, k = 0; i < ListT->Length() - 1; i++)
    for (int j = k + 1; j < this->Length(); j++)
      if (fCondition(ListT->GetNode(i), this->GetNode(j))) {
        T* temporal = this->GetNode(k)->Info();
        this->GetNode(k)->Info(NULL); this->GetNode(k++)->Info(this->GetNode(j)->Info());
        this->GetNode(j)->Info(NULL); this->GetNode(j)->Info(temporal);
      }

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
void TListE <T>::OrderListByList(TFunctionConditionalBParameters fCondition, TListE <T>* ListT, void* reference = NULL) {

  if (!ListT || !ListT->Length()) return;

  for (int i = 0, k = 0; i < ListT->Length(); i++)
    for (int j = k; j < this->Length(); j++)
      if (fCondition(ListT->GetNode(i), this->GetNode(j), reference)) {
        T* temporal = this->GetNode(k)->Info();
        this->GetNode(k)->Info(NULL); this->GetNode(k++)->Info(this->GetNode(j)->Info());
        this->GetNode(j)->Info(NULL); this->GetNode(j)->Info(temporal);
      }

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
void TListE <T>::QuickSortList(TFunctionConditionalB fCondition, void* reference = NULL) {

  this->MixList(fCondition, reference, this);

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
void TListE <T>::QuickSortList(TFunctionConditionalBParameters fCondition, void* reference = NULL, void *parameters = NULL) {

  this->MixList(fCondition, reference, parameters, this);

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
void TListE <T>::MixList(TFunctionConditionalB fCondition, void* reference, TListE <T>* array) {

  TListE <T>* array1 = new TListE <T> ();
  TListE <T>* array2 = new TListE <T> ();

  long n = array->Length(), n1, n2, i, j;

  if (n > 1) {

    if (n%2 == 0)   n1 = n2 = (long)n/2;
    else         {  n1 = (long)n/2; n2 = n1 + 1; }

    for (i = 0; i < n1; i++)      array1->Add(array->PosNode(i)->Info());
    for (j = 0; j < n2; j++, i++) array2->Add(array->PosNode(i)->Info());

    MixList(fCondition, reference, array1);
    MixList(fCondition, reference, array2);
    MixListX(fCondition, reference, array1, array2, array);

  }

  array1->TransferAll();
  array2->TransferAll();

  if (array1) delete array1;
  if (array2) delete array2;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
void TListE <T>::MixListX(TFunctionConditionalB fCondition, void* reference, TListE <T>* array1, TListE <T>* array2, TListE <T>* array3) {

  long x1 = 0, x2 = 0, x3 = 0;

  while (x1 < array1->Length() && x2 < array2->Length())
    if (fCondition(array1->PosNode(x1), array2->PosNode(x2))) {
      array3->PosNode(x3)->Info(NULL);
      array3->PosNode(x3++)->Info(array1->PosNode(x1++)->Info());
    }
    else {
      array3->PosNode(x3)->Info(NULL);
      array3->PosNode(x3++)->Info(array2->PosNode(x2++)->Info());
    }

  while (x1 < array1->Length()) { array3->PosNode(x3)->Info(NULL); array3->PosNode(x3++)->Info(array1->PosNode(x1++)->Info()); }
  while (x2 < array2->Length()) { array3->PosNode(x3)->Info(NULL); array3->PosNode(x3++)->Info(array2->PosNode(x2++)->Info()); }

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
void TListE <T>::MixList(TFunctionConditionalBParameters fCondition, void* reference, void* parameters, TListE <T>* array) {

  TListE <T>* array1 = new TListE <T> ();
  TListE <T>* array2 = new TListE <T> ();

  long n = array->Length(), n1, n2, i, j;

  if (n > 1) {

    if (n%2 == 0)   n1 = n2 = (long)n/2;
    else         {  n1 = (long)n/2; n2 = n1 + 1; }

    for (i = 0; i < n1; i++)      array1->Add(array->PosNode(i)->Info());
    for (j = 0; j < n2; j++, i++) array2->Add(array->PosNode(i)->Info());

    MixList(fCondition, reference, parameters, array1);
    MixList(fCondition, reference, parameters, array2);
    MixListX(fCondition, reference, parameters, array1, array2, array);

  }

  array1->TransferAll();
  array2->TransferAll();

  if (array1) delete array1;
  if (array2) delete array2;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
void TListE <T>::MixListX(TFunctionConditionalBParameters fCondition, void* reference, void* parameters, TListE <T>* array1, TListE <T>* array2, TListE <T>* array3) {

  long x1 = 0, x2 = 0, x3 = 0;

  while (x1 < array1->Length() && x2 < array2->Length())
    if (fCondition(array1->PosNode(x1), array2->PosNode(x2), parameters)) {
      array3->PosNode(x3)->Info(NULL);
      array3->PosNode(x3++)->Info(array1->PosNode(x1++)->Info());
    }
    else {
      array3->PosNode(x3)->Info(NULL);
      array3->PosNode(x3++)->Info(array2->PosNode(x2++)->Info());
    }

  while (x1 < array1->Length()) { array3->PosNode(x3)->Info(NULL); array3->PosNode(x3++)->Info(array1->PosNode(x1++)->Info()); }
  while (x2 < array2->Length()) { array3->PosNode(x3)->Info(NULL); array3->PosNode(x3++)->Info(array2->PosNode(x2++)->Info()); }

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
bool TListE <T>::Empty() {
  return !length;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
bool TListE <T>::Clear() {

  TNode <T>* cursor;

  while (this->first) {
    cursor = this->first;
    this->first = this->first->Next();
    if (cursor) delete cursor;
  }

  this->length   = 0;
  this->first    = NULL;
  this->final    = NULL;
  this->SetCurrent(NULL);

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
void TListE <T>::CompactListAfterOrdered(TFunctionConditionalB fCondition, void* reference = NULL) {

  long position = 0;

  while (position < this->length - 1)
    if (fCondition(this->PosNode(position), this->PosNode(position + 1)))
      this->Delete(position + 1);
    else position++;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
template <class T>
TListE <T> TListE <T>::operator=(TListE <T>& list) {

  this->Clear();

  for (int i = 0; i < list.Length(); i++) {
    TNode <T>* newNode = new TNode <T> (list.PosNode(i)->Info());
    if (this->first) {
      this->final->Next(newNode);
      newNode->Previous(this->final);
      this->final = newNode;
    }
    else this->first = this->final = newNode;
    this->length++;
  }

  this->SetCurrent(this->first);

  return *this;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
